package proyectoX.src.aplicacion;

import java.awt.Color;
import java.awt.Component;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

import proyectoX.src.fabricas.AbstractFactoryNaves;


/**
 * Corresponde al panel derecho de la interfaz y contiene todos los íconos y labels que muestran  
 * la información sobre el estado de la nave del jugador.
 * Tiene un tamaño de 80x500.
 *
 */
public class InterfazIconos extends JPanel {
	
	protected Juego juego;
	
	protected static final int WIDTH_INTERFAZ_ICONOS = 80;
	protected static final int HEIGHT_INTERFAZ_ICONOS = 500;
	
	protected static final int POSX_HP = 50;
	protected static final int POSY_HP = 70;
	
	protected JLabel vida;
	protected JLabel nivelLaser;
	protected JLabel municionesArma;
	protected JLabel municionesHabilidad;
	protected JLabel municionesBomba;
	protected JLabel puntaje;
	protected JLabel fondoIconos;
	protected Vector<JLabel> labelsPuntosDeVida;
	
	/**
	 * Inicializa todos los íconos y labels a presentar en la interfaz utilizando a la fábrica de íconos
	 * presente en el Juego pasado por parámetro.
	 * 
	 * @param j Referencia a la instancia de Juego en uso.
	 */
	public InterfazIconos(Juego j) {
		this.juego = j;
		
		ImageIcon imagen = new ImageIcon(this.getClass().getResource("/proyectoX/sprites/icons/interface_stats.png"));
		fondoIconos = new JLabel(imagen);
		fondoIconos.setBounds(0, 0, WIDTH_INTERFAZ_ICONOS, HEIGHT_INTERFAZ_ICONOS);
		fondoIconos.setVisible(true);
		
		this.setBounds(juego.getWidth()-imagen.getIconWidth(), 0, WIDTH_INTERFAZ_ICONOS, HEIGHT_INTERFAZ_ICONOS);
		this.setLayout(null);
		this.setVisible(true);
		
		this.add(fondoIconos);
		
		AbstractFactoryNaves fabricaIconos = juego.getFabricaIconos();
		
		int posXIconos = 50; 	//separación del ícono cono su label numeral
		int yIconos = 16;		//altura que se sumará para acomodar el label
		int offsetY = 40;		//separación vertical entre imágenes
		int posX = 7;			//coordenadas de la posición inicial
		int posY = 7;
		
		//Imagen de la nave del jugador
		JLabel icono = fabricaIconos.crearIconoNave(posX, posY);
		fondoIconos.add(icono);
		posY += icono.getHeight()+offsetY;
		
		//La cantidad de vidas del jugador
		icono = fabricaIconos.crearIconoVida(posX, posY);
		fondoIconos.add(icono);
		crearVida(posXIconos, posY+yIconos, yIconos);
		posY += icono.getHeight()+offsetY;
		
		//El nivel del láser de la nave
		icono = fabricaIconos.crearIconoLaser(posX, posY);
		fondoIconos.add(icono);
		crearNivelLaser(posXIconos, posY+yIconos, yIconos);
		posY += icono.getHeight()+offsetY;
		
		
		//La cantidad de municiones del arma secundario
		icono = fabricaIconos.crearIconoArma(posX, posY);
		fondoIconos.add(icono);
		crearMunicionesArma(posXIconos, posY+yIconos, yIconos);
		posY += icono.getHeight()+offsetY;
		
		
		//La cantidad de municiones de la habilidad especial
		icono = fabricaIconos.crearIconoHabilidad(posX, posY);
		fondoIconos.add(icono);
		crearMunicionesHabilidad(posXIconos, posY+yIconos, yIconos);
		posY += icono.getHeight()+offsetY;
		
		
		//La cantidad de bombas devastadoras disponibles
		icono = fabricaIconos.crearIconoBombaDevastadora(posX, posY);
		fondoIconos.add(icono);
		crearMunicionesBomba(posXIconos, posY+yIconos, yIconos);
		posY += icono.getHeight()+offsetY;
		
		
		//Puntaje actual
		crearPuntaje(posXIconos/2, posY-yIconos, yIconos);
	}
	
	
	/**
	 * En la parte superior de la interfaz y directamente debajo del ícono de la nave utilizada este método
	 * crea una "barra de vida" correspondiente a la cantidad de puntos de vida que tenga la nave actual.
	 */
	public void inicializarPuntosDeVida() {
		labelsPuntosDeVida = new Vector<JLabel>();
		ImageIcon hpNormal = new ImageIcon(this.getClass().getResource("/proyectoX/sprites/puntoDeVida.png"));

		int cant = juego.getNivelActual().obtenerNavePrincipal().getPuntosDeVida(); 
		
		//su posición inicial será en la esquina izquierda superior
		int xInicial = POSX_HP;
		int yInicial = POSY_HP;
		
		//ignoramos 1 punto de vida porque ya lo agregamos, ahora queda el resto
		for (int i = 0; i < cant; i++) {
			JLabel hp = new JLabel(hpNormal);
			hp.setBounds(xInicial, yInicial, hpNormal.getIconWidth(), hpNormal.getIconHeight());
			fondoIconos.add(hp);
			labelsPuntosDeVida.add(hp);
			xInicial -= hpNormal.getIconWidth();
		}	
	}
	
	/**
	 * Crea el label donde se irá actualizando el puntaje del jugador.
	 * 
	 * @param x Posición "x" donde se ubicará el label.
	 * @param y Posición "y" donde se ubicará el label.
	 * @param h Altura del label.
	 */
	public void crearPuntaje(int x, int y, int h) {
		puntaje= new JLabel("");
		puntaje.setBounds(x, y,80,h);
		puntaje.setSize(100,h);
		puntaje.setForeground(Color.GREEN);
		fondoIconos.add(puntaje);
	}
	
	/**
	 * Crea el label donde se irá actualizando la cantidad de vidas del jugador.
	 * 
	 * @param x Posición "x" donde se ubicará el label.
	 * @param y Posición "y" donde se ubicará el label.
	 * @param h Altura del label.
	 */
	public void crearVida(int x, int y, int h) {
		vida= new JLabel("");
		vida.setBounds(x, y,70,h);
		vida.setSize(70,h);
		vida.setForeground(Color.GREEN);
		fondoIconos.add(vida);
	}
	
	/**
	 * Crea el label donde se irá actualizando la cantidad de municiones del arma secundaria de la nave.
	 * 
	 * @param x Posición "x" donde se ubicará el label.
	 * @param y Posición "y" donde se ubicará el label.
	 * @param h Altura del label.
	 */
	public void crearMunicionesArma(int x, int y, int h) {
		municionesArma= new JLabel("");
		municionesArma.setBounds(x, y,70,h);
		municionesArma.setSize(70,h);
		municionesArma.setForeground(Color.GREEN);
		fondoIconos.add(municionesArma);
	}

	/**
	 * Crea el label donde se irá actualizando la cantidad de municiones de la habilidad especial de la nave.
	 * 
	 * @param x Posición "x" donde se ubicará el label.
	 * @param y Posición "y" donde se ubicará el label.
	 * @param h Altura del label.
	 */	
	public void crearMunicionesHabilidad(int x, int y, int h) {
		municionesHabilidad= new JLabel("");
		municionesHabilidad.setBounds(x, y,70,h);
		municionesHabilidad.setSize(70,h);
		municionesHabilidad.setForeground(Color.GREEN);
		fondoIconos.add(municionesHabilidad);
	}
	
	/**
	 * Crea el label donde se irá actualizando la cantidad de municiones de la Bomba Devastadora.
	 * 
	 * @param x Posición "x" donde se ubicará el label.
	 * @param y Posición "y" donde se ubicará el label.
	 * @param h Altura del label.
	 */
	public void crearMunicionesBomba(int x, int y, int h) {
		municionesBomba= new JLabel("");
		municionesBomba.setBounds(x, y,70,h);
		municionesBomba.setSize(70,h);
		municionesBomba.setForeground(Color.GREEN);
		fondoIconos.add(municionesBomba);
	}
	
	
	/**
	 * Crea el label donde se irá actualizando el nivel de poder del láser de la nave principal.
	 * 
	 * @param x Posición "x" donde se ubicará el label.
	 * @param y Posición "y" donde se ubicará el label.
	 * @param h Altura del label.
	 */
	public void crearNivelLaser(int x, int y, int h) {
		nivelLaser= new JLabel("");
		nivelLaser.setBounds(x, y,70,h);
		nivelLaser.setSize(70,h);
		nivelLaser.setForeground(Color.GREEN);
		fondoIconos.add(nivelLaser);
	}
	
	
	/**
	 * Agrega la cantidad de puntos de vida pasada por parámetro a la interfaz en la barra de vida.
	 * 
	 * @param cant La cantidad de puntos de vida más que se desean agregar a la interfaz.
	 */
	public void agregarPuntosDeVida(int cant) {
		
		ImageIcon hpNormal = new ImageIcon(this.getClass().getResource("/proyectoX/sprites/puntoDeVida.png"));
		
		int nuevoX = labelsPuntosDeVida.lastElement().getX()-hpNormal.getIconWidth();
		int nuevoY = labelsPuntosDeVida.lastElement().getY();
		
		for (int i = 0; i < cant; i++) {
			JLabel hp = new JLabel(hpNormal);
			hp.setBounds(nuevoX, nuevoY, hpNormal.getIconWidth(), hpNormal.getIconHeight());
			fondoIconos.add(hp);
			labelsPuntosDeVida.add(hp);
			nuevoX -= hpNormal.getIconWidth();
		}
		
		this.repaint();
	}
	
	/**
	 * Quita de la interfaz los puntos de vida pasados por parámetro y los reduce de la barra de vida.
	 * 
	 * @param cant Cantidad de puntos de vida que se desean quitar de la interfaz.
	 */
	public void quitarPuntosDeVida(int cant) {
		int pos = labelsPuntosDeVida.size()-1; //según Javadoc es la posición de la última componente agregada al vector
		Vector<JLabel> vectorAux = new Vector<JLabel>();
		
		for (int i = 0; (i < cant)&&(pos >= 0); i++) {
			vectorAux.add(labelsPuntosDeVida.elementAt(pos));
			pos--;
		}
		
		for (JLabel j : vectorAux) {
			labelsPuntosDeVida.remove(j);
			this.eliminarGraficamente(j);
		}
	}
	
	
	/**
	 * Método de limpieza para eliminar toda la barra de vida.
	 */
	public void eliminarPuntosDeVida() {
		
		for (JLabel j : labelsPuntosDeVida) {
			this.eliminarGraficamente(j);
		}
		
		labelsPuntosDeVida.clear();
	}
	
	/**
	 * Elimina la componente gráfica de la interfaz y procede a hacer un repaint.
	 * 
	 * @param c Componente a eliminar.
	 */
	private void eliminarGraficamente(Component c) {
		fondoIconos.remove(c);
		this.repaint();
	}
	
	
	/**
	 * Método utilizado para obtener el puntaje del juego y mostrar el valor actual por la interfaz.
	 */
	public void actualizarPuntaje() {
		puntaje.setText(""+juego.getNivelActual().getPuntajeParcial());
	}
	
	/**
	 * Método utilizado para obtener la cantidad de vidas de la nave jugadoray mostrar el valor actual 
	 * por la interfaz.
	 */
	public void actualizarVida() {
		vida.setText(""+juego.getNivelActual().obtenerNavePrincipal().getVida());
	}
	
	/**
	 * Método utilizado para obtener el nivel del láser de la nave jugadora y mostrar el valor actual 
	 * por la interfaz.
	 */
	public void actualizarNivelLaser() {
		nivelLaser.setText(""+juego.getNivelActual().obtenerNavePrincipal().getNivelLaser());
	}
	
	/**
	 * Método utilizado para obtener la cantidad de municiones de la habilidad especial de la nave jugadora
	 * y mostrar el valor actual por la interfaz.
	 */
	public void actualizarMunicionesHabilidad() {
		municionesHabilidad.setText(""+juego.getNivelActual().obtenerNavePrincipal().getMunicionesHabilidad());
	}
	
	/**
	 * Método utilizado para obtener la cantidad de municiones del arma secundaria de la nave jugadora
	 * y mostrar el valor actual por la interfaz.
	 */
	public void actualizarMunicionesArma() {
		municionesArma.setText(""+juego.getNivelActual().obtenerNavePrincipal().getMunicionesArma());
	}
	
	/**
	 * Método utilizado para obtener la cantidad de municiones de Bomba Devastadora que tiene la nave jugadora
	 * y mostrar el valor actual por la interfaz.
	 */
	public void actualizarMunicionesBomba() {
		municionesBomba.setText(""+juego.getNivelActual().obtenerNavePrincipal().getMunicionesBomba());
	}
	
	/**
	 * Para ser invocado luego de crear el objeto, inicializa la barra de puntos de vida y actualiza los
	 * valores correspondientes para cada dato a mostrar en la interfaz.
	 */
	public void inicializarValores() {
		inicializarPuntosDeVida();
		actualizarPuntaje();
		actualizarVida();
		actualizarNivelLaser();
		actualizarMunicionesHabilidad();
		actualizarMunicionesArma();
		actualizarMunicionesBomba();
	}

}
